package com.gec.teams.wechat.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import com.gec.teams.wechat.common.FaceComponent;
import com.gec.teams.wechat.common.UpLoadFileComponent;
import com.gec.teams.wechat.config.SystemConstants;
import com.gec.teams.wechat.exception.TeamsException;
import com.gec.teams.wechat.mapper.TbCheckinMapper;
import com.gec.teams.wechat.mapper.TbHolidaysMapper;
import com.gec.teams.wechat.mapper.TbUserMapper;
import com.gec.teams.wechat.mapper.TbWorkdayMapper;
import com.gec.teams.wechat.pojo.TbCheckin;
import com.gec.teams.wechat.pojo.TbHolidays;
import com.gec.teams.wechat.pojo.TbUser;
import com.gec.teams.wechat.pojo.TbWorkday;
import com.gec.teams.wechat.pojo.vo.CheckinFormVo;
import com.gec.teams.wechat.pojo.vo.UserDeptVo;
import com.gec.teams.wechat.service.CheckinService;
import com.gec.teams.wechat.task.EmailTask;
import com.gec.teams.wechat.util.SysDateTime;
import com.tencentcloudapi.iai.v20180301.models.VerifyPersonResponse;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 功能：签到功能Service
 * 作者：YumTea
 * 日期：2024/6/19 10:32
 */
@Service
@Slf4j
public class CheckinServiceImpl implements CheckinService {

    private static final boolean WORKDAY =true;
    private static final boolean  HOLIDAYS =false;

    @Autowired
    private TbUserMapper userMapper;
    @Autowired
    private TbWorkdayMapper workdayMapper;

    @Autowired
    private TbCheckinMapper checkinMapper;
    @Autowired
    private TbHolidaysMapper holidaysMapper;

    @Autowired
    private SystemConstants systemConstants;
    @Autowired
    private FaceComponent faceComponent;
    @Autowired
    private SysDateTime sysDateTime;
    @Autowired
    private  TbCheckinMapper tbCheckinMapper;

    @Autowired
    private EmailTask emailTask;
    @Autowired
    private UpLoadFileComponent upLoadFileComponent;

    public int getStatus(DateTime time){
        //TODO 0表示不能打卡不就好了?
        //正常上班 包括上班时间
        if(betweenTime(sysDateTime.attendanceStart,time,sysDateTime.work)){
            return 1;
        }
        //迟到状态
        if(betweenTime(sysDateTime.getWork()
                ,time
                ,sysDateTime.getAttendanceEnd())){
            return 2;
        }
        //早退
        if(betweenTime(sysDateTime.getCloseStart(),time,sysDateTime.getDown())){
            return 3;
        }
        //TODO 加班状态判断
        //下班
        if(betweenTime(sysDateTime.getDown(),time,sysDateTime.getCloseEnd())){
            return 4;
        }
        //其他时候都不给考勤
        return 0;
    }

    //相等等于0 大于返回1 小于返回-1
    //包括 startTime和endTime
    public boolean betweenTime(DateTime startTime,  DateTime nowTime ,DateTime endTime){
        if(nowTime.compareTo(startTime)>=0&&nowTime.compareTo(endTime)<=0) return true;
        return false;
    }
    @Override
    public String validCanCheckin(int userId, String today) {
        //这是判断是否上班的变量,默认是可以上班
        boolean workDay = WORKDAY;
        //先查出来今天是特殊工作日还是特殊节假日
        boolean isWorkDay= workdayMapper.isTodayWorkDay() !=null ?true:false;
        boolean isHoliday = holidaysMapper.isTodayHoliday() != null ? true : false;
        //先查今天是不是周末，再查是不是特殊节假日或工作日
        if(DateUtil.date().isWeekend()){
            workDay= HOLIDAYS;
        }
        if(isWorkDay){
            workDay= WORKDAY;
        }else if(isHoliday){
            workDay= HOLIDAYS;
        }
        //开始判断是否需要考勤
//        if(!workDay){
//            throw new TeamsException("今天不用上班！");
//        }

        //开始判断这个时间段可以不可以签到
        DateTime now = DateUtil.date();

        //判断一下在不在可以考勤的时间范围内
        //判断当前是上班考勤还是下班考勤 还有考勤状态
        int status = getStatus(now);
        System.out.println("当前时间为"+now+",状态为："+status);
//        if(status==0) throw new TeamsException("现在不是考勤时段",501);
        //开始判断你是不是已经签到过了
        String start="";
        String end="";
        if(status<=2) {
            start = systemConstants.getAttendanceStartTime();
             end = systemConstants.getAttendanceEndTime();
        }else{
            start = systemConstants.getClosingStartTime();
            end = systemConstants.getClosingEndTime();
        }
        HashMap map = new HashMap();
        map.put("userId",userId);
        map.put("start",start);
        map.put("end",end);
        //判断有没有签到过
        Integer integer = checkinMapper.haveCheckin(map);
        boolean bool = integer != null ? true : false;
        System.out.println(integer);
        if(bool) throw new TeamsException("你都签过了还签,爪巴");
//        checkinMapper.insert(TbCheckin.builder()
//                        .
//                .build())
        return "可以正常考勤";
    }


    //能跑了先不动他了
    @Override
    public void checkin(HashMap hashMap) {
        DateTime now=DateUtil.date();
        int status=getStatus(now);
//        if(status==0) throw new TeamsException("超出考勤时间段,无法考勤");
        Integer userId = (Integer) hashMap.get("userId");
//        判断我们有没有这个人的人脸
        boolean userInfo = faceComponent.getUserInfo(userId.toString());
        if(!userInfo){
            throw new TeamsException("不存在人脸模型");
        }
          //检查是不是人脸是不是对的上
        MultipartFile file = (MultipartFile) hashMap.get("file");
        VerifyPersonResponse resp = faceComponent.verifyUser(userId.toString()
                    ,  file);
            Boolean isMatch = resp.getIsMatch();
            if(!isMatch)  throw new TeamsException("签到无效，非本人签到");
        String fileUrl = upLoadFileComponent.uploadFile(file, status);
        System.out.println(fileUrl);
        //可以开始弄好数据插入了
         CheckinFormVo form = (CheckinFormVo) hashMap.get("form");
        TbCheckin tbCheckin = TbCheckin.builder()
                .userId(userId)
                .faceUrl(fileUrl)
                .createTime(now)
                .status(status)
                .date(new Date())
                .build();
        BeanUtils.copyProperties(form,tbCheckin);
        //插入
        tbCheckinMapper.insertSelective(tbCheckin);
        //TODO 迟到了就发消息给老板
        //创建一个 SimpleMailMessage对象
        //先查出来是谁签到,还要把部门拿出来！
        UserDeptVo userDeptVo = userMapper.getUserAndDept(userId);
        SimpleMailMessage message = new SimpleMailMessage();
        //这个是标题
        message.setSubject(userDeptVo.getDept().getDeptName()+"的员工"+userDeptVo.getName()+"打卡通知");
        //        设置文本内容
        message.setText(userDeptVo.getDept().getDeptName()+"的员工"+userDeptVo.getName()+"在"+form.getAddress()+"的"+now+"签到了");

        emailTask.sendAsync(message);
    }

    @Override
    public ArrayList<HashMap> searchWeekCheckin(HashMap param) {
        //先查出来 这一周的考勤记录
        ArrayList<HashMap> checkinList = tbCheckinMapper.searchWeekCheckin(param);
        //查出来 这周的特殊节假日
        ArrayList<String> holidayList = tbCheckinMapper.searchHolidaysInRange(param);
        ArrayList<String> workdayList = tbCheckinMapper.searchWorkdayInRange(param);
        //把特殊节假日和工作日 添加到 考勤记录中
        DateTime startDate = DateUtil.parse(param.get("startDate").toString());
        DateTime endDate = DateUtil.parse(param.get("endDate").toString());
//        日期范围生成器
        DateRange range = DateUtil.range(startDate, endDate, DateField.DAY_OF_YEAR);

        ArrayList<HashMap> list=new ArrayList<>();
        for (DateTime one : range) {
            String date = one.toString("yyyy-MM-dd");
            //查出来这一星期的每天是上班还是放假 默认是工作日
            String type="工作日";
            if(one.isWeekend()) type="节假日";
            if(holidayList!=null&&holidayList.contains(date)) type="节假日";
            if(workdayList!=null&&workdayList.contains(date)) type="工作日";
            String status="";
//            查询状态,还有判定当前日期是不是还没到呢
            if(type.equals("工作日")&&DateUtil.compare(one,DateUtil.date())<=0){
                status="缺勤";
                //flag证明有考勤记录
                boolean flag=false;
//                遍历一边考勤记录，如果有今天的考情记录，把在数据库里面的考勤状态拿出来
                    //TODO 还要加多一个判断下班有没有早退,现在只是取最后一个考勤的状态，要两个都是正常
                for (HashMap map : checkinList) {
                    if(map.containsValue(date)){
                        status= (String) map.get("status");
                        flag=true;
//                        break;
                    }
                }
//                如果是当天还没结束考勤的情况 Status不用帮忙查询
                String today=DateUtil.today();
                if(today.equals(date)&&DateUtil.date().isBefore(sysDateTime.attendanceEnd)&&flag==false) status="";
            }
            HashMap map = new HashMap();
            map.put("type",type);
            map.put("status",status);
            map.put("date",date);
            map.put("day",one.dayOfWeekEnum().toChinese("周"));
            list.add(map);
        }
        return list;
    }


    //TODO 这个累计签到肯定要优化一下的，毕竟我是上班下班才算一次
    @Override
    public long searchCheckinDays(int userId) {
        List<Integer> list = tbCheckinMapper.searchCheckinDays(userId);
        long size = list.size();
        return size;
    }

    @Override
    public HashMap searchTodayCheckin(int userId) {
        return tbCheckinMapper.searchTodayCheckin(userId);
    }

}
